﻿namespace SampleApplication.ViewModels
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using Microsoft.Practices.Prism.Interactivity.InteractionRequest;
    using Okazuki.MVVM.PrismSupport.Utils;
    using Okazuki.MVVM.PrismSupport.ViewModels;
    using SampleApplication.Models;
    using System.Diagnostics;
    using Microsoft.Practices.Prism.Commands;

    public partial class MainViewModel : ViewModelBase
    {
        private IUnitOfWork UnitOfWork;
        private PersonRepository personRepository;

        public MainViewModel()
            : this(null)
        {
        }

        public MainViewModel(IUnitOfWork unit)
        {
            this.UnitOfWork = unit ?? new SampleContext();
            this.personRepository = new PersonRepository(this.UnitOfWork);
        }

        [AutoInit]
        public ObservableCollection<PersonRecordViewModel> People { get; private set; }

        [AutoInit]
        public InteractionRequest<Confirmation> ShowPersonRequest { get; private set; }

        [AutoInit]
        public InteractionRequest<Notification> ShowMessageRequest { get; private set; }

        [AutoInitCommand]
        public DelegateCommand<PersonRecordViewModel> EditCommand { get; private set; }

        [AutoInitCommand]
        public DelegateCommand<string> LoadCommand { get; private set; }

        [AutoInitCommand]
        public DelegateCommand<PersonRecordViewModel> DeleteCommand { get; private set; }

        [AutoInitCommand]
        public DelegateCommand InsertCommand { get; private set; }

        [CommandMethod]
        private void EditExecute(PersonRecordViewModel parameter)
        {
            var conf = new Confirmation
            {
                Title = "編集画面",
                Content = new PersonViewModel(parameter.Model)
            };

            this.ShowPersonRequest.Raise(conf, p =>
            {
                if (p.Confirmed)
                {
                    var ret = this.UnitOfWork.SaveChanges();
                    parameter.ApplyModelProperty();
                    this.ShowMessageRequest.Raise(
                        new Notification
                        {
                            Content = string.Format("{0}のデータを更新しました。", parameter.Name)
                        });
                }
            });
        }

        [CommandMethod]
        private bool CanEditExecute(PersonRecordViewModel parameter)
        {
            return parameter != null;
        }

        [CommandMethod]
        private void LoadExecute(string name)
        {
            this.People.Clear();
            var ret = this.personRepository.Search(name).Take(500);
            foreach (var p in ret)
            {
                this.People.Add(new PersonRecordViewModel(this, p));
            }

            if (this.People.Count >= 500)
            {
                this.ShowMessageRequest.Raise(
                    new Notification
                    {
                        Content = "データ件数が500件を超えています。最初の500件を表示しています。"
                    });
            }
            else
            {
                this.ShowMessageRequest.Raise(
                    new Notification
                    {
                        Content = string.Format("{0}件のデータが見つかりました", this.People.Count)
                    });
            }
        }

        [CommandMethod]
        private void DeleteExecute(PersonRecordViewModel parameter)
        {
            this.personRepository.Delete(parameter.Model);
            if (this.UnitOfWork.SaveChanges() == 1)
            {
                this.People.Remove(parameter);
                this.ShowMessageRequest.Raise(
                    new Notification
                    {
                        Content = string.Format("{0}を削除しました", parameter.Name)
                    });
            }
        }

        [CommandMethod]
        private bool CanDeleteExecute(PersonRecordViewModel parameter)
        {
            return parameter != null;
        }

        [CommandMethod]
        private void InsertExecute()
        {
            var personViewModel = new PersonViewModel(new Person());
            this.ShowPersonRequest.Raise(
                new Confirmation
                {
                    Title = "新規登録",
                    Content = personViewModel
                },
                conf =>
                {
                    if (!conf.Confirmed)
                    {
                        return;
                    }
                    this.personRepository.Insert(personViewModel.Model);
                    var ret = this.UnitOfWork.SaveChanges();
                    if (ret == 1)
                    {
                        this.People.Add(
                            new PersonRecordViewModel(this, personViewModel.Model));
                        this.ShowMessageRequest.Raise(
                            new Notification
                            {
                                Content = string.Format("{0}を登録しました", personViewModel.Name)
                            });
                    }
                });
        }
    }
}
